package sdp;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * SimWorld extends World, to provide a simulated environment for the Robot. Rather than using the physical
 * world, SimWorld provides a means for testing various strategies, logic and control of the system through
 * a rudimentary physics simulation.
 * 
 * @author ronan, kieran
 */
public class SimWorld extends World {

	/** 
	 * Construct world using given settings. 
	 * */
	public SimWorld( Settings settings ) {
		super(settings);
		
		// Load image files for the simulation
		try {
			imgBackground = ImageIO.read(new File(pathBackground));
			imgYellowRobot = ImageIO.read(new File(pathYellowRobot));
			imgBlueRobot = ImageIO.read(new File(pathBlueRobot));
			imgBall = ImageIO.read(new File(pathBall));
		} catch (IOException ex) {
			
			// Exit if we couldn't load images - cannot run simulation if so
			ex.printStackTrace();
			System.err.println("Failed to load simulator images");
			return;
		}
		
		// Create our window for drawing
		window = new JFrame("Simulation");
		
		window.setSize(imgBackground.getWidth(), imgBackground.getHeight());
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setResizable(false);
		
		// Override paintComponent method of JPanel to perform custom painting
		JPanel panel = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				
				// Call our drawing method
				paintWorld(g);
			}
		};
		window.add(panel);
		window.setVisible(true);
	}
	
	/**
	 * Our custom drawing method for the simulation. Draws our pitch, ball and robots at
	 * their respective positions.
	 * 
	 * @param g The graphics to draw to.
	 */
	public void paintWorld(Graphics g) {
		
		// Draw the pitch
		g.drawImage(imgBackground, 0, 0, null);
		
		// Draw the robots
		RobotState player = getPlayerState();
		RobotState opponent = getOpponentState();
		
		paintRobot(g, player);
		paintRobot(g, opponent);
		
		// Draw the ball
		BallState ball = getBallState();
		
		g.drawImage(imgBall, (int)ball.getPosition().getX(), (int)ball.getPosition().getY(), null);
	}
	
	/**
	 * Method to paint a given RobotState, rotated, at it's position, with the correct colour.
	 * 
	 * @param g 		The graphics to draw to.
	 * @param robot		The RobotState to draw.
	 */
	private void paintRobot(Graphics g, RobotState robot ){
		Graphics2D g2d = (Graphics2D) g;
		AffineTransform affineTransform = new AffineTransform();
		
		// Translate to the robot's position
		affineTransform.setToTranslation((robot.getPosition().getX()),robot.getPosition().getY()); 
		
		// Anchor around the centre of the image and rotate to preserve positioning
		affineTransform.rotate(robot.getRotation(),(imgYellowRobot.getWidth())/2,(imgYellowRobot.getHeight())/2);
		
		// Draw the correct colour for our robot with the setup AffineTransform
		g2d.drawImage(robot.getTeam()== RobotState.Team.BLUE ? imgBlueRobot : imgYellowRobot, affineTransform, null);
		
	}
	
	@Override
	protected void update() {
		// Do nothing so far.
	}
	
	/**
	 * Test main entry-point for the Simulator
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		
		// Construct a basic settings object
		Settings worldSettings = new Settings();
		
		worldSettings.playerState = new RobotState(RobotState.Team.BLUE, new Vector2(0, 0), new Vector2(20, 20), 0);
		worldSettings.opponentState = new RobotState(RobotState.Team.YELLOW, new Vector2(0, 0), new Vector2(20, 20), Math.toRadians(45));
		worldSettings.ballState = new BallState(new Vector2(50, 50), 5);
		
		worldSettings.pitchBottomLeft = new Vector2(0,0);
		worldSettings.pitchTopRight = new Vector2(0,0);
		worldSettings.motorCount = 4;
		
		// Create our SimWorld - this displays a JFrame which will stay alive until closing the window
		SimWorld world = new SimWorld(worldSettings);
	}
	
	// The window used to display the simulation
	private JFrame window;
	
	// The image file paths (relative) to the starting directory.
	private static String pathBackground = "Data/bg.png";
	private static String pathYellowRobot = "Data/yellow_robot.png";
	private static String pathBlueRobot = "Data/blue_robot.png";
	private static String pathBall = "Data/ball.png";
		
	// The loaded images to display
	private static BufferedImage imgBackground;
	private static BufferedImage imgYellowRobot;
	private static BufferedImage imgBlueRobot;
	private static BufferedImage imgBall;
	
}
